import moment from 'moment';

import { TRMessage } from '#/components';
import { HttpCode } from '#/utils/contacts';
import {
  fetchUnitLimitPowerPageViewData,
  fetchPrograms,
  fetchHourOrderInfo,
  fetchUnit,
  fetchTradeTime,
} from '@/pages/Tianji/TenDaysCentralizedBidding/services';
import { getStationLevelThree } from '@/services/user';
import { TradeStrategy, SubmitType } from '@/pages/Tianji/TenDaysCentralizedBidding/constant';
import { getDefaultProgramId } from './helper';

let timeout;
const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));
const delayClear = (time) =>
  new Promise((resolve) => {
    clearTimeout(timeout);
    timeout = setTimeout(resolve, time);
  });

export default {
  namespace: 'tenDaysCentralizedBidding',
  state: {
    tradeCenterTime: null, // 交易中心时间
    tradeDate: null, // 当前交易日期
    tradeSeqId: null, // 当前交易序列id
    tradeSeqInfo: {}, // 当前交易序列信息
    unitLimitInfo: {}, // 所有交易单元限额信息
    programList: [], // 方案列表
    currentProgramId: null, // 当前选中方案id
    currentProgramInfo: {}, // 当前选中方案信息
    unitInfo: {}, // 所有交易单元限额信息
    initProgramInfo: {}, // 当前序列初始化方案数据
    loadingNum: 0, // 全局loading效果
    showMain: false, // Main组件是否显示
    hasModified: false, // 当前方案是否被修改过
    selectedRowKeys: [], // 选择的时点行
    // usedUnitList: [], // 被方案占用的交易单元列表
    stations: [], // 全部场站（平铺）
    stationTree: [], // 已选省份的场站树
    selectedUnitIds: [], // 已选择交易单元id
    formData: {}, // 保存查询参数
    stationCapacityInfo: {}, //所有场站装机容量信息
    maxValue: 0, //申报电量固定值上限
  },
  reducers: {
    setTradeCenterTime(state, { payload }) {
      return { ...state, tradeCenterTime: payload };
    },
    setTradeDate(state, { payload }) {
      return { ...state, tradeDate: payload };
    },
    setTradeSeqId(state, { payload }) {
      return { ...state, tradeSeqId: payload };
    },
    setTradeSeqInfo(state, { payload }) {
      return { ...state, tradeSeqInfo: payload };
    },
    setUnitLimitInfo(state, { payload }) {
      return { ...state, unitLimitInfo: payload };
    },
    setProgramList(state, { payload }) {
      return { ...state, programList: payload };
    },
    setCurrentProgramId(state, { payload }) {
      return { ...state, currentProgramId: payload };
    },
    setCurrentProgramInfo(state, { payload }) {
      return { ...state, currentProgramInfo: payload };
    },
    setUnitInfo(state, { payload }) {
      return { ...state, unitInfo: payload };
    },
    setStationCapacityInfo(state, { payload }) {
      return { ...state, stationCapacityInfo: payload };
    },
    setMaxValue(state, { payload }) {
      return { ...state, maxValue: payload };
    },
    setInitProgramInfo(state, { payload }) {
      return { ...state, initProgramInfo: payload };
    },
    setAddLoadingNum(state) {
      return { ...state, loadingNum: state.loadingNum + 1 };
    },
    setSubLoadingNum(state) {
      return { ...state, loadingNum: state.loadingNum - 1 };
    },
    setShowMain(state, { payload }) {
      return { ...state, showMain: payload };
    },
    setHasModified(state, { payload }) {
      return { ...state, hasModified: payload };
    },
    setSelectedRowKeys(state, { payload }) {
      return { ...state, selectedRowKeys: payload };
    },
    setStations(state, { payload }) {
      return { ...state, stations: payload };
    },
    setStationTree(state, { payload }) {
      return { ...state, stationTree: payload };
    },
    setSelectedUnitIds(state, { payload }) {
      return { ...state, selectedUnitIds: payload };
    },
    setFormData(state, { payload }) {
      return { ...state, formData: payload };
    },
  },
  effects: {
    // 修改方案信息
    *editProgramInfoEffect({ payload }, { call, put }) {
      yield put({
        type: 'setCurrentProgramInfo',
        payload: payload,
      });
      yield put({
        type: 'setHasModified',
        payload: true,
      });
    },
    // 用于分单元限额页面展示
    *fetchUnitLimitInfoEffect({ payload }, { call, put, select }) {
      yield put({
        type: 'setAddLoadingNum',
      });
      let global = yield select((_) => _.global);
      let menuCode = global.configure.menuCode;

      let currentState = yield select((_) => _.tenDaysCentralizedBidding);

      const res = yield call(fetchUnitLimitPowerPageViewData, currentState.tradeSeqId, menuCode);
      yield put({
        type: 'setSubLoadingNum',
      });
      if (res && res?.statusCode === HttpCode.SUCCESS) {
        yield put({
          type: 'setUnitLimitInfo',
          payload: res.data,
        });
      } else {
        TRMessage.error(res?.message || '获取分单元限额信息失败');
      }
    },
    // 获取方案列表
    *fetchProgramsEffect({ payload }, { call, put, select }) {
      yield put({
        type: 'setAddLoadingNum',
      });
      let currentState = yield select((_) => _.tenDaysCentralizedBidding);

      const tradeSeqId = currentState.tradeSeqId;
      //将山西交易中心ID和交易序列拆开
      const _tradeSeqId = tradeSeqId.includes('PHBSX')
        ? tradeSeqId
        : currentState.formData?.marketId + tradeSeqId;

      const res = yield call(fetchPrograms, _tradeSeqId, false);
      yield put({
        type: 'setSubLoadingNum',
      });
      if (res && res?.statusCode === HttpCode.SUCCESS) {
        if (!res.data.programList.length) {
          yield put({
            type: 'setProgramList',
            payload: [],
          });
          return;
        }
        // 对方案进行排序：已申报(2) 申报锁定(1) 一般状态(0) 新建(-1，新建不需要在这里进行处理)
        let submited = [],
          locked = [],
          saved = [];
        res.data.programList.forEach((item) => {
          switch (item.status) {
            case 2:
              submited.push(item);
              break;
            case 1:
              locked.push(item);
              break;
            case 0:
              saved.push(item);
              break;
          }
        });
        let programList = [...submited, ...locked, ...saved];
        yield put({
          type: 'setProgramList',
          payload: programList,
        });
        if (payload?.setDefaultProgramId) {
          let global = yield select((_) => _.global);
          let defaultProgramId = getDefaultProgramId(
            programList,
            global.configure.currentUser.name,
          );
          yield put({
            type: 'setCurrentProgramId',
            payload: defaultProgramId,
          });
          yield put({
            type: 'fetchHourOrderInfoEffect',
            payload: defaultProgramId,
          });
        }
      } else {
        TRMessage.error(res?.message || '获取方案列表失败');
      }
    },
    // 获取方案下的时段信息
    *fetchHourOrderInfoEffect({ payload }, { call, put, select }) {
      // 如果为-1，则为新增方案，设置为当前序列初始化方案数据，不需要去请求相关配置
      let currentState = yield select((_) => _.tenDaysCentralizedBidding);
      if (payload === '-1') {
        yield put({
          type: 'setCurrentProgramInfo',
          payload: currentState.initProgramInfo,
        });
        return;
      }
      let global = yield select((_) => _.global);
      let menuCode = global.configure.menuCode;
      yield put({
        type: 'setAddLoadingNum',
      });
      const res = yield call(fetchHourOrderInfo, menuCode, payload);
      yield put({
        type: 'setSubLoadingNum',
      });
      if (res?.statusCode === HttpCode.SUCCESS) {
        yield put({
          type: 'setHasModified',
          payload: false,
        });
        const formData = currentState.formData;
        if (formData?.marketId === 'PHBSD' && res.data?.hourOrderInfoList) {
          res.data.hourOrderInfoList = (res.data?.hourOrderInfoList || []).map((t) => {
            t.hourOrder = t.date;
            return t;
          });
        }
        yield put({
          type: 'setCurrentProgramInfo',
          payload: res.data,
        });
        // 在方案列表里同步删除权限
        let programListData = JSON.parse(JSON.stringify(currentState.programList));
        programListData.forEach((item) => {
          if (item.id === res.data.programInfo.id) {
            item.deletePermission = res.data.deletePermission;
            item.status = res.data.programInfo.status;
          }
        });
        yield put({
          type: 'setProgramList',
          payload: programListData,
        });
      } else {
        TRMessage.error(res?.message || '获取方案下的时段信息失败');
      }
    },
    // 设置当前序列初始化方案数据
    *initProgramInfoEffect({ payload }, { call, put, select }) {
      let currentState = yield select((_) => _.tenDaysCentralizedBidding);
      let unitInfo = currentState.unitInfo;
      const formData = currentState.formData;
      let data = {
        deletePermission: true,
        editPermission: true,
        programInfo: {
          adjust: true,
        },
        hourOrderInfoList: [],
      };
      if (formData.marketId === 'PHBSX') {
        for (let i = 1; i <= 24; i++) {
          data.hourOrderInfoList.push({
            buyLimit: 0,
            firstPrice: 0,
            firstSubmitPower: 0,
            hourOrder: i,
            lowerPrice: Object.values(unitInfo)[0]?.limitMapping?.[i]?.unitLowerPrice, //[0] 同一省份交易上下限额相同 取其中一项即可
            programId: 0,
            secondPrice: 0,
            secondSubmitPower: 0,
            sellLimit: 0,
            submitType: SubmitType.INSTALLED_CAPACITY,
            totalPower: 0,
            tradeStrategy: TradeStrategy.NO_STRATEGY,
            upperPrice: Object.values(unitInfo)[0]?.limitMapping?.[i]?.unitUpperPrice,
          });
        }
      } else {
        //[0] 同一省份交易上下限额相同 取其中一项即可
        Object.entries(Object.values(unitInfo)[0]?.limitDateMapping || {}).forEach((t) => {
          data.hourOrderInfoList.push({
            buyLimit: 0,
            firstPrice: 0,
            firstSubmitPower: 0,
            hourOrder: t[0],
            date: t[0],
            lowerPrice: t[1]?.unitLowerPrice,
            programId: 0,
            secondPrice: 0,
            secondSubmitPower: 0,
            sellLimit: 0,
            submitType: SubmitType.INSTALLED_CAPACITY,
            totalPower: 0,
            tradeStrategy: TradeStrategy.NOT_DEAL,
            upperPrice: t[1]?.unitUpperPrice,
          });
        });
      }
      //  2024-08-28 处理点切换省份后点击查询 当前列表数据不切换bug
      yield put({
        type: 'setCurrentProgramInfo',
        payload: data,
      });
      yield put({
        type: 'setInitProgramInfo',
        payload: data,
      });
    },
    // 获取序列下交易单元限额信息
    *fetchUnitEffect({ payload }, { call, put, select }) {
      yield put({
        type: 'setAddLoadingNum',
      });
      let global = yield select((_) => _.global);
      let menuCode = global.configure.menuCode;

      let currentState = yield select((_) => _.tenDaysCentralizedBidding);

      const tradeSeqId = currentState.tradeSeqId;
      //将山西交易中心ID和交易序列拆开
      const _tradeSeqId = tradeSeqId.includes('PHBSX')
        ? tradeSeqId.slice(0, 5) + '/' + tradeSeqId
        : currentState.formData?.marketId + '/' + tradeSeqId;
      const param = {
        stationIds: [],
        marketId: currentState.formData?.marketId,
      };
      const res = yield call(fetchUnit, _tradeSeqId, menuCode, param);
      yield put({
        type: 'setSubLoadingNum',
      });
      if (res?.statusCode === HttpCode.SUCCESS) {
        yield put({
          type: 'setUnitInfo',
          payload: res.data.unitInfoMapping,
        });
        yield put({
          type: 'setStationCapacityInfo',
          payload: res.data.stationCapacity,
        });
        yield put({
          type: 'initProgramInfoEffect',
        });
      } else {
        TRMessage.error(res?.message || '获取序列下交易单元限额信息失败');
      }
    },
    // 点击查询按钮的副作用
    *handleSearchEffect({ payload }, { call, put, select }) {
      let currentState = yield select((_) => _.tenDaysCentralizedBidding);
      const tradeSeqId = currentState.tradeSeqId;
      // 获取所有交易单元限额信息
      if (tradeSeqId.includes('PHBSX')) {
        yield put({
          type: 'fetchUnitLimitInfoEffect',
        });
      }

      // 获取方案列表
      yield put({
        type: 'fetchProgramsEffect',
        payload: {
          setDefaultProgramId: true,
        },
      });
      // 获取序列下交易单元限额信息
      yield put({
        type: 'fetchUnitEffect',
      });
    },
    *getStationLevelThreeEffect({ payload }, { call, put, select }) {
      // yield put({
      //   type: 'setAddLoadingNum',
      // });
      // let global = yield select((_) => _.global);
      // const res = yield call(getStationLevelThree, global.configure.menuCode);
      // yield put({
      //   type: 'setSubLoadingNum',
      // });

      // if (res?.statusCode === HttpCode.SUCCESS) {
      //   let data = res?.data;

      //   // 处理数据权限
      //   if (!data) {
      //     TRMessage.error('暂无数据权限');
      //     return;
      //   }

      // 当前过滤为山西
      // let stationTree =
      //   data.filter((item) => {
      //     return item?.value === '14';
      //   })[0]?.children || [];

      let stationTree = payload?.children || [];

      // 处理数据。为了适用子组件，所有公司及场站增加key title字段，key = value title = label
      stationTree.forEach((company) => {
        company?.value && (company.key = company.value);
        company?.label && (company.title = company.label);
        (company?.children || []).forEach((station) => {
          station?.value && (station.key = station.value);
          station?.label && (station.title = station.label);
        });
      });

      let stations = [];

      stationTree.forEach((company) => {
        (company?.children || []).forEach((station) => {
          stations.push(station);
        });
      });

      yield put({
        type: 'setStations',
        payload: stations,
      });
      yield put({
        type: 'setStationTree',
        payload: stationTree,
      });
      // } else {
      //   TRMessage.error(res?.message || '获取交易单元信息失败');
      // }
    },
    // 每隔30s同步交易中心时间
    *fetchTradeTimeEffect({ payload }, { call, put, select }) {
      const res = yield call(fetchTradeTime);
      if (res?.statusCode === HttpCode.SUCCESS) {
        yield put({
          type: 'setTradeCenterTime',
          payload: moment(res.data.time),
        });
        yield put({
          type: 'updateTradeTimeEffect',
        });
      } else {
        TRMessage.error(res?.message || '获取交易中心时间失败');
      }
      yield delay(30 * 1000);
      yield put({
        type: 'fetchTradeTimeEffect',
      });
    },
    // 每隔一秒更新交易中心时间
    *updateTradeTimeEffect({ payload }, { call, put, select }) {
      yield delayClear(1 * 1000);
      let currentState = yield select((_) => _.tenDaysCentralizedBidding);
      let time = moment(currentState.tradeCenterTime);
      time.add(1, 's');
      yield put({
        type: 'setTradeCenterTime',
        payload: moment(time),
      });
      yield put({
        type: 'updateTradeTimeEffect',
      });
    },
  },
};
